package oracle.apps.financials.collection.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Random;

import oracle.apps.financials.collection.po.Collector;
import oracle.apps.financials.collection.po.Customer;
import oracle.apps.financials.collection.po.Metrics;
import oracle.apps.financials.collection.po.MetricsItem;
import oracle.apps.financials.collection.po.MetricsItemValueHolder;
import oracle.apps.financials.collection.po.PercentMetricsItemValueHolder;
import android.text.TextUtils;

import com.j256.ormlite.dao.ForeignCollection;

public class MockDataFactory {

	private static List<Customer> customerList = new ArrayList<Customer>();
	private static List<Collector> collectorList = new ArrayList<Collector>();

	private static List<MetricsItem> metricsItemList = new ArrayList<MetricsItem>();

	public final static int size = 365 * 3;

	public static List<Date> dateValues = new ArrayList<Date>();
	public static Date[] WhitedateValues = new Date[11];

	public static Random random = new Random();

	public static String[] customerNames = new String[] { "IBM", "Microsoft", "Dell", "Bank of America", "Yamaha", "Red Robin", "Apple", "OOCL",
			"Cosco", "Oracle", "Tencent", "Baidu", "Alcoa" };

	// public static String[] customerNames = new String[] { "IBM", "Microsoft"
	// };

	public static String[] collectorNames = new String[] { "Lucas", "Kery", "Libing", "Susan", "Ken", "Joe", "Michael", "Richard Liu", "Joshua",
			"Ruby", "Tony", "Jeff", "Monica" };

	public String bu[] = new String[] { "Vision Operations", "Vision Operations (USA)", "Vision Foods", "Vision XY" };

	public static String DATE_FORMAT = "yyyy/MM/dd";
	public static SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);

	static {

		dateValues.add(getTime(new Date(), Calendar.MONTH, -36));

		for (int i = 0; i < size - 1; i++) {

			dateValues.add(getTime(dateValues.get(i), Calendar.DATE, 1));
			// System.out.println(dateFormat.format(dateValues.get(i)));
		}

	}

	public static List<Customer> getCustomerList() {
		if (customerList.isEmpty()) {
			for (int i = 0; i < customerNames.length; i++) {
				customerList.add(initCustomer(i, customerNames[i], collectorNames[i]));
			}

			customerList.get(0).setCollector(collectorList.get(1));
			collectorList.get(1).getCustomerList().add(customerList.get(0));

		}
		return customerList;
	}

	public static List<MetricsItem> getMetricsItemList() {
		if (metricsItemList.isEmpty()) {
			for (int i = 0; i < getCustomerList().size(); i++) {

				List<List<Double>> percentcurrentYValueList = customerList.get(i).getMetrics().getPercentCurrent().getyValueList();

				List<List<Double>> dsoYValueList = customerList.get(i).getMetrics().getDSO().getyValueList();

				for (int j = 0; j < size - 1; j++) {

					MetricsItem item = new MetricsItem();

					item.setItemTime(dateValues.get(j));
					item.setNetBalance(1000 + Math.abs(random.nextInt()) % 150);
					item.setAccountOverdue(600 + Math.abs(random.nextInt()) % 150);
					item.setCurrency("USD");

					item.setDaysSalesOutstanding(40 + Math.abs(random.nextInt()) % 15);
					item.setTrueDSO(36 + Math.abs(random.nextInt()) % 15);
					item.setBestPossibleDSO(30 + Math.abs(random.nextInt()) % 15);
					item.setSalesWeightedDSO(30 + Math.abs(random.nextInt()) % 15);
					item.setSalesWeightedDSOAvg(40);

					item.setStrategyEffectiveness(0.5 + Math.abs(random.nextInt()) % 15);
					item.setTotalReceipt(20 + Math.abs(random.nextInt()) % 15);

					item.setAverageDaysLate(43 + Math.abs(random.nextInt()) % 15);
					item.setWeightedAverageDaysPaid(45 + Math.abs(random.nextInt()) % 15);
					item.setWeightedAverageDaysLate(41 + Math.abs(random.nextInt()) % 15);

					item.setPercent90OverDaysDelinquentAvg(37);

					item.setPercentCurrent(percentcurrentYValueList.get(0).get(j));
					item.setPercent1To30DaysDelinquent(percentcurrentYValueList.get(1).get(j));
					item.setPercent31To60DaysDelinquent(percentcurrentYValueList.get(2).get(j));
					item.setPercent61To90DaysDelinquent(percentcurrentYValueList.get(3).get(j));
					item.setPercent90OverDaysDelinquent(percentcurrentYValueList.get(4).get(j));
					item.setCustomer(customerList.get(i));
					metricsItemList.add(item);
				}
			}
		}
		return metricsItemList;
	}

	public static void convertMetricsItems(Customer customer) {

		ForeignCollection<MetricsItem> metricsItemList = customer.getMetricsItemList();

		if (metricsItemList != null && !metricsItemList.isEmpty()) {

			List<MetricsItem> list = new ArrayList<MetricsItem>();
			for (MetricsItem item : metricsItemList) {
				list.add(item);
			}
			Collections.sort(list);

			PercentMetricsItemValueHolder percentCurrent = customer.getMetrics().getPercentCurrent();

			List<Double> yValue = new ArrayList<Double>();
			List<Double> y1Value = new ArrayList<Double>();// 1-30
			List<Double> y2Value = new ArrayList<Double>();// 31-60
			List<Double> y3Value = new ArrayList<Double>();// 61-90
			List<Double> y4Value = new ArrayList<Double>();// 91++
			List<Double> y5Value = new ArrayList<Double>();// prior year
			List<Date> dateValues = new ArrayList<Date>();

			for (MetricsItem item : list) {
				dateValues.add(item.getItemTime());
				yValue.add(item.getPercentCurrent());
				y1Value.add(item.getPercent1To30DaysDelinquent());
				y2Value.add(item.getPercent31To60DaysDelinquent());
				y3Value.add(item.getPercent61To90DaysDelinquent());
				y4Value.add(item.getPercent90OverDaysDelinquent());

			}
			int index = 365;
			for (int j = yValue.size() - 1; j > -1; j--) {
				y5Value.add(j > index ? yValue.get(j - index) : yValue.get(j%yValue.size()));
			}

			percentCurrent.setCurrentX(dateValues.get(dateValues.size() - 1).getTime());

			percentCurrent.getyValueList().add(yValue);
			percentCurrent.getyValueList().add(y1Value);
			percentCurrent.getyValueList().add(y2Value);
			percentCurrent.getyValueList().add(y3Value);
			percentCurrent.getyValueList().add(y4Value);
			percentCurrent.getyValueList().add(y5Value);

			percentCurrent.getxValueList().add(dateValues);
			percentCurrent.getxValueList().add(dateValues);
			percentCurrent.getxValueList().add(dateValues);

			percentCurrent.getxValueList().add(dateValues);
			percentCurrent.getxValueList().add(dateValues);
			percentCurrent.getxValueList().add(dateValues);
			// customer.getMetrics().getDSO().getxValueList().add(dateValues);

			initDSO(customer.getMetrics().getDSO());
		}
	}

	public static Date getTime(Date date, int time, int value) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.add(time, value);
		return calendar.getTime();
	}

	public static List<Collector> getCollectorList(String collectorName) {
		List<Collector> list = new ArrayList<Collector>();
		if (TextUtils.isEmpty(collectorName)) {
			list = collectorList;
		} else {
			for (int i = 0; i < collectorNames.length; i++) {
				if (collectorNames[i].toLowerCase().contains(collectorName.toLowerCase())) {
					list.add(collectorList.get(i));
				}
			}
		}

		return list;
	}

	public static Customer getCustomerByName(String CustomerName) {

		Customer customer = null;
		if (TextUtils.isEmpty(CustomerName)) {
			return null;
		}
		for (int i = 0; i < customerNames.length; i++) {
			if (customerNames[i].equalsIgnoreCase(CustomerName)) {
				customer = getCustomerList().get(i);
			}
		}
		return customer;
	}

	public static Collector getCollectorByName(String name) {

		Collector obj = null;
		if (TextUtils.isEmpty(name)) {
			return null;
		}
		for (int i = 0; i < collectorNames.length; i++) {
			if (collectorNames[i].equalsIgnoreCase(name)) {
				obj = getCollectorList().get(i);
			}
		}
		return obj;
	}

	public static Customer initCustomer(int i, String customerName, String collectorName) {

		Customer customer = new Customer();
		customer.setCustomerName(customerName);

		customer.setPrimaryContact("Contact " + i);

		customer.setBusinessLevel("Customer Level " + i);
		customer.setAddress("Hi-tech Park Building " + i);
		customer.setEmail("lucas.xu." + i + "@oracle.com");
		customer.setPhone("0755-3212222-" + i);
		customer.setStrategy("strategy " + i);
		customer.setNote("customer note information " + i);

		Metrics metrics = new Metrics();

		initPercentCurrent(metrics.getPercentCurrent());
		initDSO(metrics.getDSO());

		customer.setMetrics(metrics);

		Collector collector = new Collector();
		collector.setCollectorName(collectorName);
		collector.setCEI("100.0" + i);
		collector.setAddress("Fiyta Building China" + i);
		collector.setEmail("lucas.xu." + i + "@IBM.com");
		collector.setPhone("0755-3212222-" + i);
		collector.setLanguage("Chinese,English");
		collector.setIndustry("Commercial Stage");
		collector.setTimeZone("Pacific Standard Time");
		collector.setAvailability("Y");
		collector.setRegion("US");
		collector.setSpeciallyBucket("Early Stage");

		customer.setCollector(collector);
		collector.getCustomerList().add(customer);

		collectorList.add(collector);

		return customer;
	}

	public static void initPercentCurrent(PercentMetricsItemValueHolder percentCurrent) {
		List<Double> yValue = new ArrayList<Double>();
		List<Double> y1Value = new ArrayList<Double>();// 1-30
		List<Double> y2Value = new ArrayList<Double>();// 31-60
		List<Double> y3Value = new ArrayList<Double>();// 61-90
		List<Double> y4Value = new ArrayList<Double>();// 91++
		List<Double> y5Value = new ArrayList<Double>();// prior year

		double lastRandY = 26;
		double lastRandY1 = 20;
		double lastRandY2 = 25;
		double lastRandY3 = 16;

		for (int j = 0; j < size; j++) {

			lastRandY = getNextValueByBand(lastRandY, 50, 20);

			lastRandY1 = getNextValueByBand(lastRandY1, 20, 10);

			lastRandY2 = getNextValueByBand(lastRandY2, 20, 6);

			lastRandY3 = getNextValueByBand(lastRandY3, 20, 8);

			if (lastRandY + lastRandY1 + lastRandY2 >= 90) {
				lastRandY1 = lastRandY1 - random.nextInt(5);
				lastRandY2 = lastRandY2 - random.nextInt(5);
				lastRandY3 = random.nextInt(10);
			}

			yValue.add(lastRandY);
			y1Value.add(lastRandY1);
			y2Value.add(lastRandY2);
			y3Value.add(lastRandY3);
			y4Value.add((double) ((long) (100 - yValue.get(j) - y1Value.get(j) - y2Value.get(j) - y3Value.get(j))));
		}

		int index = 365;

		for (int j = yValue.size() - 1; j > -1; j--) {
			y5Value.add(j > index && j - index < yValue.size() ? yValue.get(j - index) : getNextValueByBand(y5Value.get(y5Value.size() - 1), 45, 8));
		}

		percentCurrent.setCurrentX(dateValues.get(dateValues.size() - 1).getTime());

		percentCurrent.getyValueList().add(0, yValue);
		percentCurrent.getyValueList().add(1, y1Value);
		percentCurrent.getyValueList().add(2, y2Value);
		percentCurrent.getyValueList().add(3, y3Value);
		percentCurrent.getyValueList().add(4, y4Value);
		percentCurrent.getyValueList().add(5, y5Value);

		percentCurrent.getxValueList().add(dateValues);
		percentCurrent.getxValueList().add(dateValues);
		percentCurrent.getxValueList().add(dateValues);
		percentCurrent.getxValueList().add(dateValues);
		percentCurrent.getxValueList().add(dateValues);
		percentCurrent.getxValueList().add(dateValues);
	}

	public static double getNextValueByBand(double lastRand, float max, float min) {
		lastRand = random.nextBoolean() ? lastRand + random.nextFloat() : lastRand - random.nextFloat();
		lastRand = lastRand > max ? lastRand - random.nextInt(4) : (lastRand < min ? lastRand + random.nextInt(4) : lastRand);
		return (double) ((long) (lastRand * 100)) / 100;
	}

	private static void initDSO(MetricsItemValueHolder dso) {

		// 1, 2, 3, 4 are values for DSO For All, Prior Period, Best Possible
		// DSO, No of Collectors
		List<Double> y1Value = new ArrayList<Double>();
		List<Double> y2Value = new ArrayList<Double>();
		List<Double> y3Value = new ArrayList<Double>();
		List<Double> y4Value = new ArrayList<Double>();

		// DSO Value for Customer
		List<Double> y5Value = new ArrayList<Double>();

		double lastRandY1 = 30;
		double lastRandY2 = 25;
		double lastRandY3 = 40;
		double lastRandY5 = 20;

		for (int j = 0; j < size; j++) {

			lastRandY5 = getNextValueByBand(lastRandY5, 55, 20);

			lastRandY1 = getNextValueByBand(lastRandY1, 55, 25);

			lastRandY2 = getNextValueByBand(lastRandY2, 55, 10);

			lastRandY3 = random.nextBoolean() ? lastRandY3 + (int) random.nextFloat() : lastRandY3 - (int) random.nextFloat();
			lastRandY3 = lastRandY3 > lastRandY5 ? lastRandY5 - random.nextInt(3) : (lastRandY3 < 18 ? lastRandY3 + random.nextInt(4) : lastRandY3);

			y1Value.add(lastRandY1);
			y2Value.add(lastRandY2);
			y3Value.add(lastRandY3);
			y4Value.add(Math.abs(random.nextInt(800)) + 10 + 0.0);
			y5Value.add(lastRandY5);
		}

		dso.setCurrentX(y5Value.get(y5Value.size() - 1));

		dso.getyValueList().add(y5Value);
		dso.getyValueList().add(y1Value);
		dso.getyValueList().add(y2Value);
		dso.getyValueList().add(y3Value);
		dso.getyValueList().add(y4Value);

		// dso.setxValueList(dateValues);
		dso.getxValueList().add(dateValues);
		// dso.getxValueList().add(dateValues);
		// dso.getxValueList().add(dateValues);
		// dso.getxValueList().add(dateValues);
		// dso.getxValueList().add(dateValues);

	}

	public static void convertMetricsToMetricsItem(Customer customer, Date itemTime) {

		PercentMetricsItemValueHolder percentCurrent = customer.getMetrics().getPercentCurrent();
		List<Double> yValue = (List<Double>) (percentCurrent.getxValueList().get(0));
	}

	public static List<Collector> getCollectorList() {
		return collectorList;
	}

	public static void setCollectorList(List<Collector> collectorList) {
		MockDataFactory.collectorList = collectorList;
	}

}
